home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Cheat II / cheat.c next >
Text File  |  1995-09-05  |  14KB  |  544 lines

  1. // cheat.c
  2. // an excuse for a filename
  3.  
  4. #include <string.h>
  5. #include <pascal.h>
  6. #include "main.h"
  7. #include "cheatWindow.h"
  8. #include "ResRefs.h"
  9. #include "cheat.h"
  10. #include "error.h"
  11. #include "cheatwich.h"
  12. #include "cheatfile.h"
  13.  
  14. shortcut wichcuts[kmaxwichcuts];
  15. int numwichcuts = 0;
  16.  
  17.     // test if a char is fit to be processed by the TEManager
  18. int numbKey(char c)        // a numb key is defined by not having feelings
  19.                             // (boy am I witty)
  20. {
  21.     int res = false, i;
  22.     char *valid = " 0123456789.-";
  23.     
  24.     valid[0] = (char) 8;        // delete, I think
  25.     for (i=0;valid[i];i++)
  26.         res |= (c == valid[i]);
  27.     return res;
  28. }
  29.  
  30.  
  31.     // pop up a simple alert with given string as the text, one okay button
  32. void stdmessage(Str255 s)
  33. {
  34.     ParamText(s, "\p", "\p", "\p");
  35.     (void) Alert(rmessagealrt, nil);
  36. }
  37.  
  38.  
  39.     // converts the text in the TE field to a longint
  40. long HandToLong(TEHandle h)
  41. {
  42.     Str255 str;
  43.     long l;
  44.     int i;
  45.  
  46.     str[0] = (char) (**h).teLength;
  47.     for (i=1;i<=str[0], i<200;i++)
  48.         str[i] = ((*((char **) (**h).hText))[i-1]);
  49.     StringToNum(str, &l);
  50.     return l;
  51. }
  52.  
  53.     // moves the text in the TE into scratch
  54. static void HandToScratch(TEHandle h)
  55. {
  56.     int i;
  57.     for (i=0;i<256;i++)
  58.         scratch[i] = ((*((char **) (**h).hText))[i]);
  59.     scratch[i] = 0;
  60.     if ((**h).teLength < 256)
  61.         scratch[(**h).teLength] = 0;
  62. }
  63.  
  64.     // when the user hits a key, let's do some shit
  65. void HandleKey(char c)
  66. {
  67.     float diff;
  68.     int i;
  69.     
  70.     if (numbKey(c)) {
  71.     }
  72. }
  73.  
  74.  
  75.     // the user hit the search button, so let's do it
  76. void searchButtonHit(void)
  77. {
  78.     Cell cell = {0, 0};
  79.     int *pint, findint, temp;
  80.     void *p;
  81.     long endsearch, findlong, newposs, *plong, l, startsearch;
  82.     Str255 str;
  83.     Boolean isbolo;
  84.     
  85.         // get the number to search for from the text field
  86.     GetIText(ditem[riSearchNum], str);
  87.     StringToNum(str, &findlong);
  88.     findint = findlong;
  89.  
  90.     if (LGetSelect(true, &cell, plist)) {        // must have selected an app
  91.         isbolo = *((long *) ((long) InfoRec[cell.v].processName + 1)) == 'Bolo';
  92.         
  93.         if (isbolo)
  94.             gcurposs = 0;
  95.         else {
  96.         p = (void *) ((long) InfoRec[cell.v].processLocation + InfoRec[cell.v].processSize);
  97.         startsearch = (long) p;
  98.         if (!gcurposs) {    // starting a new search
  99.                 // p is start of search, at the largest location in that app's partition
  100.             endsearch = (long) InfoRec[cell.v].processLocation;
  101.             pint = (int *) p; plong = (long *) p;
  102.             
  103.             switch (gvalsize) {
  104.                 case ksizelong:
  105.                     while ((long) plong >= endsearch) {
  106.                         plong = (long *) ((long) plong - 2);    // only decrement two bytes
  107.                         if (*plong == findlong) {        // we've found a possibility
  108.                             gposs[gcurposs++] = (Ptr) plong;    // store it
  109.                             if (gcurposs>=gmaxposs)        // too many values
  110.                                 plong = (void *) (endsearch-4);        // this will kill the search
  111.                         }
  112.                     }
  113.                     break;
  114.                 case ksizeint:
  115.                     while ((long) pint >= endsearch)
  116.                         if (*--pint == findint) {        // we've found a possibility
  117.                             gposs[gcurposs++] = (Ptr) pint;    // store it
  118.                             if (gcurposs>=gmaxposs)        // too many values
  119.                                 pint = (void *) (endsearch-4);        // this will kill the search
  120.                         }
  121.                     break;
  122.                 case ksizebyte:
  123.                     while ((long) pint >= endsearch) {
  124.                         pint--;
  125.                             // first look at high-order byte
  126.                         temp = (*pint) >> 8;
  127.                         if (temp == findint) {        // we've found a possibility
  128.                             gposs[gcurposs++] = (Ptr) pint;    // store it
  129.                             if (gcurposs>=gmaxposs)        // too many values
  130.                                 pint = (void *) (endsearch-4);        // this will kill the search
  131.                         }
  132.                             // now look at low-order byte
  133.                         temp = (*pint) & 0xFF;
  134.                         if (temp == findint) {        // we've found a possibility
  135.                             gposs[gcurposs++] = (Ptr) ((long) pint + 1);    // store it
  136.                             if (gcurposs>=gmaxposs)        // too many values
  137.                                 pint = (void *) (endsearch-4);        // this will kill the search
  138.                         }
  139.                     }
  140.                     break;
  141.                 default: break;
  142.             }
  143.         }
  144.         else {        // refining a search
  145.             newposs = 0;
  146.             switch (gvalsize) {
  147.                 case ksizelong:        // we're dealing in longints
  148.                     for (l=0;l<gcurposs;l++)
  149.                         if (*((long *)gposs[l]) == findlong)
  150.                             gposs[newposs++] = gposs[l];
  151.                     break;
  152.                 case ksizeint:        // we're dealing in integers
  153.                     for (l=0;l<gcurposs;l++)
  154.                         if (*((int *)gposs[l]) == findint)
  155.                             gposs[newposs++] = gposs[l];
  156.                     break;
  157.                 case ksizebyte:        // we're dealing in bytes
  158.                     for (l=0;l<gcurposs;l++)
  159.                         if ((long) gposs[l] & 1) {    // some are odd
  160.                                 // extract low order byte
  161.                             if ((*((int *)((long) gposs[l] - 1)) & 0xFF) == findint)
  162.                                 gposs[newposs++] = gposs[l];
  163.                         }
  164.                         else if ((*((int *)gposs[l]) >> 8) == findint)
  165.                             gposs[newposs++] = gposs[l];
  166.                     break;
  167.                 default: break;
  168.             }
  169.             gcurposs = newposs;
  170.         }
  171.         }
  172.         
  173.             // change the text field of the possibilities item
  174.         NumToString(gcurposs, str);
  175.         SetIText(ditem[riPossibilities], str);
  176.             // change the text field of the offset item
  177.         goffset = startsearch - (long) gposs[0];
  178.         if (gcurposs)
  179.             NumToString(goffset, str);
  180.         else
  181.             str[0] = 0;        // empty string
  182.         SetIText(ditem[riOffset], str);
  183.     }
  184.     DrawFoundPic();        // might have narrowed, etc
  185.     fixshortbuttz();
  186. }
  187.  
  188.  
  189.     // called when user switches apps or hits Start Over button
  190. void doStartOver(void)
  191. {
  192.     Str255 str = "\p0";
  193.     
  194.     SetIText(ditem[riPossibilities], str);
  195. //    SetIText(ditem[riSearchNum], str);
  196.     gcurposs = 0;
  197.     
  198.         // clear the offset text
  199.     str[0] = 0;
  200.     SetIText(ditem[riOffset], str);
  201.     goffset = 0;
  202.     
  203.     DrawFoundPic();        // definitely clouds
  204.     fixshortbuttz();
  205. }
  206.  
  207.  
  208.     // called when user selects the size of what they're searching for
  209. void doSizeChange(short item)
  210. {    
  211.     Str255 str = "\p0";
  212.     
  213.     setSearchSize(item - riSizeLong);
  214.         // we unfortunately must reset some things, but not everything
  215.     SetIText(ditem[riPossibilities], str);
  216.     gcurposs = 0;
  217.  
  218.         // clear the offset text
  219.     str[0] = 0;
  220.     SetIText(ditem[riOffset], str);
  221.     goffset = 0;
  222.     
  223.     DrawFoundPic();        // definitely clouds
  224.     fixshortbuttz();
  225. }
  226.  
  227.  
  228.     // called when user selects how they want to find the process
  229. void doRuptOrSelect(short item)
  230. {
  231.     int delta = item - riSelecting;
  232.     Cell cell = {0, 0};
  233.     
  234.     if (ghowfind == delta)
  235.         return;        // no need
  236.         
  237.     setFindGameBy(delta);
  238.     if (delta)
  239.         installTMTask();
  240.     else
  241.         removeTMTask();
  242.     if (LGetSelect(true, &cell, plist))
  243.         LSetSelect(false, cell, plist);
  244. }
  245.  
  246.  
  247.     // called when a user hits the change button
  248. void doChange(void)
  249. {
  250.     Cell cell = {0, 0};
  251.     Str255 str;
  252.     long l;
  253.     int changeto, *ip, temp;
  254.     short res;
  255.  
  256.     if (goffset == 0) {
  257.         stdmessage("\pError: offset of 0 cannot be valid");
  258.         return;
  259.     }
  260.     if (LGetSelect(true, &cell, plist)) {        // must have selected an app
  261.         if (gcurposs>1) {        // they have more than one piece of data they want to change
  262.             res = Alert(rYouSureAlrt, 0);        // ask them
  263.             if (res != 1)
  264.                 return;        // their mistake
  265.         }
  266.         GetIText(ditem[riNewValue], str);
  267.         StringToNum(str, &l);
  268.         changeto = l;
  269.         switch (gvalsize) {
  270.             case ksizelong:        // we're dealing in longints
  271.                 *((long *) gposs[0]) = l;        // set the place in memory!
  272.                 break;
  273.             case ksizeint:        // we're dealing in integers
  274.                 if (l > 65535) {
  275.                     stdmessage("\pError: Change To value is too large for integer.");
  276.                     return;
  277.                 }
  278.                 *((int *) gposs[0]) = changeto;        // set the place in memory!
  279.                 break;
  280.             case ksizebyte:
  281.                 if (l > 255) {
  282.                     stdmessage("\pError: Change To value is too large for byte.");
  283.                     return;
  284.                 }
  285.                 if ((long) gposs[0] & 1) {        // odd address
  286.                     ip = (int *) ((long) gposs[0] - 1);        // set at word right before byte
  287.                         // change the low-order byte of this word to what we want
  288.                     temp = (((*ip) >> 8) << 8) + (changeto & 0xFF);
  289.                     *ip = temp;        // set it in memory
  290.                 }
  291.                 else {
  292.                     ip = (int *) gposs[0];        // treat as word pointer
  293.                         // change the high-order byte of this word to what we want
  294.                     temp = (((*ip) << 8) >> 8) + ((changeto & 0xFF) << 8);
  295.                     *ip = temp;        // set it in memory
  296.                 }
  297.                 break;
  298.             default: verify(false); break;
  299.         }
  300.     }
  301. }
  302.  
  303.  
  304.     // user clicks on Add button in Cheat Sheet
  305. void doAddCheat(void)
  306. {
  307.     shortcut newcut;
  308.     Str255 s;
  309.     long l;
  310.     short id;
  311.     Cell cell, well = {0, 0};
  312.     Handle h;
  313.     
  314.     if (!gcurposs) {
  315.         stdmessage("\pSorry, you haven't located a cheat yet.");
  316.         return;
  317.     }
  318. //    if (!LGetSelect(true, &well, plist)) {        // find selected app
  319. //        stdmessage("\pYou must have a game selected when adding a cheat.");
  320. //        return;
  321. //    }
  322.         // fill fields of the struct w/ appropriate values
  323.         // damn, I should be reading Plato right now
  324.     GetIText(ditem[riTitle], newcut.title);
  325.     if (!newcut.title[0]) {
  326.         stdmessage("\pYou must enter a title before adding a cheat.");
  327.         return;
  328.     }
  329.     if (goffset>150000)
  330.         stdmessage("\pWarning: value saved is reasonably likely to move about, thus saved position may not work again.");
  331.     GetIText(ditem[riComment], newcut.comment);
  332.     GetIText(ditem[riNewValue], s);
  333.     StringToNum(s, &newcut.newval);
  334.     newcut.datasize = gvalsize;
  335.     if (LGetSelect(true, &well, plist)) {
  336.         l = (long) InfoRec[well.v].processLocation + InfoRec[well.v].processSize;
  337.         newcut.offset = l - (long) gposs[0];
  338.     }
  339.     else
  340.         newcut.offset = goffset;
  341.     
  342.         // try to grow our records
  343.     SetHandleSize((Handle) cut, sizeof(shortcut) * (gnumcuts + 1));
  344.     if (MemError()) {
  345.         stdmessage("\pSorry, there is not enough memory allocated to remember this cheat.");
  346.         return;
  347.     }
  348.     HLock((Handle) cut);
  349.     (*cut)[gnumcuts] = newcut;
  350.     HUnlock((Handle) cut);
  351.  
  352.     
  353.         // add a cell in the list
  354.     cell.v = LAddRow(1, -1, slist);
  355.     cell.h = 0;
  356.     LSetCell((Ptr) &newcut.title[1], newcut.title[0], cell, slist);
  357.     
  358.     gnumcuts++;
  359.     
  360.         // add the resource to our file
  361.     h = NewHandle(sizeof(shortcut));
  362.     verify(h);
  363.     HLock(h);
  364.     **((shortcut **) h) = newcut;
  365.     HUnlock(h);
  366.     id = Unique1ID(kcheatsheettype);
  367.     AddResource(h, kcheatsheettype, id, newcut.title);
  368.     if (ResError())
  369.         stdmessage("\pI was unable to save this cheat.");
  370.     else {
  371.         WriteResource(h);
  372.         ReleaseResource(h);
  373.     }
  374.     // DisposHandle(h);
  375. }
  376.  
  377.  
  378.     // save the shortcuts that were saved into ram during the last cheatwich
  379. void addwichcuts (void)
  380. {
  381.     shortcut newcut;
  382.     Str255 s;
  383.     long l;
  384.     short id;
  385.     Cell cell, well = {0, 0};
  386.     Handle h;
  387.     int i;
  388.     
  389.     for (i=0;i<numwichcuts;i++) {
  390.         newcut = wichcuts[i];
  391.         verify(cut);
  392.         SetHandleSize((Handle) cut, sizeof(shortcut) * (gnumcuts + 1));
  393.         if (MemError()) {
  394.             stdmessage("\pSorry, there is not enough memory allocated to remember this cheat.");
  395.             return;
  396.         }
  397.         HLock((Handle) cut);
  398.         (*cut)[gnumcuts] = newcut;
  399.         HUnlock((Handle) cut);
  400.     
  401.             // add a cell in the list
  402.         cell.v = LAddRow(1, -1, slist);
  403.         cell.h = 0;
  404.         LSetCell((Ptr) &newcut.title[1], newcut.title[0], cell, slist);
  405.         
  406.         gnumcuts++;
  407.         
  408.             // add the resource to our file
  409.         h = NewHandle(sizeof(shortcut));
  410.         verify(h);
  411.         HLock(h);
  412.         **((shortcut **) h) = newcut;
  413.         HUnlock(h);
  414.         id = Unique1ID(kcheatsheettype);
  415.         AddResource(h, kcheatsheettype, id, newcut.title);
  416.         if (ResError())
  417.             stdmessage("\pI was unable to save this cheat.");
  418.         else {
  419.             WriteResource(h);
  420.             ReleaseResource(h);
  421.         }
  422.     }
  423.  
  424.     numwichcuts = 0;
  425. }
  426.  
  427.     // called when a user hits the open cheat button or double clicks on a cell
  428. void doOpenCheat(void)
  429. {
  430.     Cell cell = {0, 0}, well = {0, 0};
  431.     Str255 str;
  432.     long l;
  433.     short res;
  434.  
  435.     if (!LGetSelect(true, &well, plist)) {
  436.         stdmessage("\pYou must have a game selected before opening a cheat.");
  437.         return;
  438.     }
  439.     if (LGetSelect(true, &cell, slist)) {        // must have selected a shortcut
  440.         HLock((Handle) cut);
  441.         
  442.             // we want to transfer data to the main window, etc.
  443.         gcurposs = 1;
  444.         NumToString(gcurposs, str);
  445.         SetIText(ditem[riPossibilities], str);
  446.         gposs[0] = (Ptr) ((long) InfoRec[well.v].processLocation + 
  447.                 InfoRec[well.v].processSize - (*cut)[cell.v].offset);
  448.         goffset = (*cut)[cell.v].offset;
  449.         NumToString(goffset, str);
  450.         SetIText(ditem[riOffset], str);
  451.         NumToString((*cut)[cell.v].newval, str);
  452.         SetIText(ditem[riNewValue], str);
  453.         verify((*cut)[cell.v].datasize >=0 && (*cut)[cell.v].datasize <= 2);
  454.         setSearchSize((*cut)[cell.v].datasize);
  455.         SetIText(ditem[riTitle], (*cut)[cell.v].title);
  456.         SetIText(ditem[riComment], (*cut)[cell.v].comment);
  457.         
  458.         HUnlock((Handle) cut);
  459.  
  460.         DrawFoundPic();        // might change
  461.         fixshortbuttz();
  462.     }
  463. }
  464.  
  465.     // return the length of the selection (in cells) of the slist
  466. static int selength(void)
  467. {
  468.     Cell cell = {0, 0};
  469.     int count = 1;
  470.     
  471.     if (!LGetSelect(true, &cell, slist))
  472.         return 0;
  473.     cell.v++;
  474.     while (LGetSelect(false, &cell, slist)) {
  475.         count++;
  476.         cell.v++;
  477.     }
  478.     return count;
  479. }
  480.  
  481.     // user clicks on Remove button in Cheat Sheet
  482. void doRemoveCheat(void)
  483. {
  484.     shortcut newcut;
  485.     Str255 s;
  486.     long l;
  487.     short i, woop;
  488.     Cell cell = {0, 0};
  489.     Handle h;
  490.     int sels = selength();
  491.     
  492.     if (!LGetSelect(true, &cell, slist)) {        // find selected app
  493.         stdmessage("\pYou must have a cheat selected.");
  494.         return;
  495.     }
  496.     
  497.     HLock((Handle) cut);
  498.  
  499.     for (woop=0; woop < sels; woop++) {
  500.         LDelRow(1, cell.v, slist);        // remove from list
  501.             // remove from resource fork
  502.         h = Get1NamedResource(kcheatsheettype, (*cut)[cell.v].title);
  503.         if (h)
  504.             RmveResource(h);
  505.         if (ResError())
  506.             stdmessage("\pAn error occurred, and I was unable to remove this cheat from the file.");
  507.         
  508.             // slide information down
  509.         for (i = cell.v; i + 1 < gnumcuts; i++)
  510.             (*cut)[i] = (*cut)[i+1];
  511.     }
  512.     
  513.     HUnlock((Handle) cut);
  514.     gnumcuts--;
  515. }
  516.  
  517. void doExportShortcut(int how)
  518. {
  519.     Cell cell = {0, 0};
  520.  
  521.     if (!LGetSelect(true, &cell, slist)) {
  522.         stdmessage("\pYou must have a game selected before opening a cheat.");
  523.         return;
  524.     }
  525.     if (LGetSelect(true, &cell, slist)) {        // must have selected a shortcut
  526.         HLock((Handle) cut);
  527.         doSaveFile(how, &((*cut)[cell.v]), selength());
  528.         HUnlock((Handle) cut);
  529.     }
  530. }
  531.  
  532. extern int wegotfile;    // from cheatfile
  533.  
  534. void fixshortbuttz(void)
  535. {
  536.     int sels = selength();
  537.  
  538.     HiliteControl((ControlHandle) sitem[riExportNew], sels ? 0 : 255);
  539.     HiliteControl((ControlHandle) sitem[riAppendToOld], (sels&&wegotfile) ? 0 : 255);
  540.     HiliteControl((ControlHandle) sitem[riExportAppend], sels ? 0 : 255);
  541.     HiliteControl((ControlHandle) sitem[riOpenCheat],  (sels == 1) ? 0 : 255);
  542.     HiliteControl((ControlHandle) sitem[riRemoveCheat],  sels ? 0 : 255);
  543.     HiliteControl((ControlHandle) sitem[riAddCheat], goffset ? 0 : 255);
  544. }